/*****************************************************************************/
/*                        >>> FUNC_consola.c -- <<<                          */
/*	Trabajo Practico 2do. cuatrimestre 2011                                  */
/*	TP:"FUSELAJE"                                                            */
/*	GRUPO: Reduce Fat Fast                                                   */
/*	INTEGRANTES: Emanuel Genovese                                            */
/*               Federico Gabriel Garcia                                     */
/*               Federico Pioli                                              */
/*               Esther Insfrain                                             */
/*               Luciano Bagattin                                            */
/*	Fecha UM:                                                                */
/*****************************************************************************/
/*****************************************************************************/
/*		        	Include					                                 */
/*****************************************************************************/
#include <string.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include "../headers/constantes.h"
#include "../headers/structs_consola.h"
#include "../headers/prototipos.h"
#include "../headers/func_PCNIPC.h"
#include "log.h"
#include "func_strings.h"
#include "constants_commons.h"


/******************************************************************************/
/* Nombre de Funcion: fAtenderPosicionCabezal                                 */
/* Parametros: socket: socket por el cual se comunica                         */
/*               log: archivo de log                                          */
/* Descripcion: Funcion que envia al Ppd la posicion del cabezal              */
/******************************************************************************/
int fAtenderPosicionCabezal(int iSocket, vecTrace * iPosicion, t_log *log) {
	/*declaracion de variables locales*/
	stNIPC st, str;
	int iResultado = -1;
	vecTrace iResult;
	void * sPayload;
	void * sPayload1 = NULL;

	/*fin de la declaracion variables locales*/

	st.iPayloadDescriptor = POSICIONCABEZAL;

	st.iType = 1;

	st.sPayload_lenth = 0;

	strcpy(st.sDescriptorOriginal, "NULL");

	sPayload = NULL;

	if (fSendIPCCXsocket(iSocket, st, sPayload, log) == 0) {
		log_error(log, NOMBREPROCESO, "Message error: %s",
				"Error en el envio de pedido de atencion de cabezal");
		return -1;
	}
	log_info(log, NOMBREPROCESO, "Message info: %s",
			"Exito en el envio de pedido de atencion de cabezal");

	/*Procedemos a esperar el pedido*/

	if (fRecvIPCCXsocket(iSocket, &str, &sPayload1, log) <= 0) {
		log_error(log, NOMBREPROCESO, "Message error: %s",
				"Error en la recepcion de pedido de atencion de cabezal");
		return -1;
	} //fin del if
	log_info(log, NOMBREPROCESO, "Message info: %s",
			"Exito en la recepcion de pedido de atencion de cabezal");
	//iPosicion=(int *)*sPayload1;
	iResult= *(vecTrace*)sPayload1;
	*iPosicion=iResult;


	iResultado = 0;

	return iResultado;
} //find el fAtenderPosicionCabezal

/******************************************************************************/
/* Nombre de Funcion: fAtenderClean                                           */
/* Parametros: iSocket: socket por el cual se comunica                        */
/*               sectorDesde: sector por el cual va a empezar a borrar        */
/*               sectorHasta: sector por el cual va a terminar de borrar      */
/*               inclusive                                                    */
/*             log: archivo log                                               */
/* Descripcion: Funcion que envia el pedido al ppd para limpiar sectores      */
/******************************************************************************/

int fAtenderClean(int iSocket, int sectorDesde, int sectorHasta,
		char * sectoresBorrados, char * sectoresNoBorrados,
		int *iCantSectoresBorrados, int *iCantSectoresNoBorrados, t_log *log) {
	/*declaracion de variables locales*/
	stNIPC st, str;
	int i, iCantSectores = 0, iResp;
	stREscrituraSector iResultado;
	stPEscrituraSector stIPC;
	void * sPayload = NULL;
	void *sPayload1 = NULL;
    char sCadenaLog[1024]="\0";
	char sSector[10];

	/*fin de la declaracion variables locales*/
	st.iPayloadDescriptor = ESCRITURA;
	st.iType = 2;

	st.sPayload_lenth = sizeof(stPEscrituraSector);
	sprintf(sectoresBorrados, "%s", "");
	sprintf(sectoresNoBorrados, "%s", "");
	strcpy(st.sDescriptorOriginal, "NULL");
	memset(stIPC.info, '\0', 512);
	iCantSectores = sectorHasta - sectorDesde;
	for (i = sectorDesde; i <= sectorHasta; i++) {
		stIPC.iSector = i;
		sPayload = (void *) &stIPC;
		memset(sCadenaLog, '\0', 1024);
		/*Enviamos el pedido de borrado del sector*/
		if (fSendIPCCXsocket(iSocket, st, sPayload, log) == 0) {

			sprintf(sCadenaLog, "%s%d", "Error en el envio de pedido de borrado del sector ", stIPC.iSector);
			log_error(log, NOMBREPROCESO, "Message error: %s",
					sCadenaLog);
			return 1;
		} //fin del if
        sprintf(sCadenaLog, "%s%d", "Exito en el envio de pedido de borrado del sector ", stIPC.iSector);
		log_info(log, NOMBREPROCESO, "Message info: %s",
				sCadenaLog);

		/*Procedemos a recibir la respuesta del PPD acerca del borrado de dicho sector*/
		if (fRecvIPCCXsocket(iSocket, &str, &sPayload1, log) <= 0) {
			memset(sCadenaLog, '\0', 1024);
			sprintf(sCadenaLog, "%s%d","Error en la recepcion de pedido de borrado del sector ", stIPC.iSector);
			log_error(log, NOMBREPROCESO, "Message error: %s",
					sCadenaLog);
			iResp = 1;

		} //fin del if
		memset(sCadenaLog, '\0', 1024);
		sprintf(sCadenaLog,"%s%d", "Exito en la recepcion de pedido de borrado del sector",stIPC.iSector);
		log_info(log, NOMBREPROCESO, "Message info: %s",
				sCadenaLog);
		iResultado = *(stREscrituraSector*) sPayload1;

		/*Verifico si la operacion salio ok*/
		if (iResultado.iRespuesta == OPERACION_OK) {
			iCantSectoresBorrados++;
			pIntacad(i, sSector);
			strcat(sectoresBorrados, sSector);
			strcat(sectoresBorrados, ",");
			iResp=0;
		} else {
			iCantSectoresNoBorrados++;
			pIntacad(i, sSector);
			strcat(sectoresBorrados, sSector);
			strcat(sectoresBorrados, ",");
			iResp=1;
		}
	}

	return iResp;
} //fin del fAtenderClean

/******************************************************************************/
/* Nombre de Funcion: fAtenderTrace                                           */
/* Parametros: iSocket: socket de comunicacion con el PPD.                    */
/*             sectores:sectores a Tracear no deben ser mas de 5              */
/* Descripcion: Funcion atiende el trace                                      */
/******************************************************************************/
int fAtenderTrace(int iSocket, int vTrace[5], int iCant,  t_log *log) {
	/*declaracion de variables locales*/
	stNIPC st;
	int  i;
	stNIPC str;
	void * sPayload=NULL;
	void * sPayload1 = NULL;
	stTrace v;

	/*fin de la declaracion variables locales*/
	st.iPayloadDescriptor = TRACE;
	st.iType = 4;
	st.sPayload_lenth = sizeof(int);


    /*Procedo a enviar los pedidos de trace*/
	strcpy(st.sDescriptorOriginal, "NULL");
	for (i = 0; i <= iCant; i++) {
		sPayload = (void *)&vTrace[i];
		if (fSendIPCCXsocket(iSocket, st, sPayload, log)==0) {
			log_error(log, NOMBREPROCESO, "Message error: %s",
										"Error en el envio de pedido del trace del sector");
			return -1;
		} //fin del if
		log_info(log, NOMBREPROCESO, "Message info: %s",
									"Exito en el envio de pedido del trace del sector");

	} //fin del for

	/*Recibo los pedidos de trace a medida que me van atendiendo*/
	for (i = 0; i <= iCant; i++) {

		if (fRecvIPCCXsocket(iSocket, &str, sPayload1, log)<=0) {
			log_error(log, NOMBREPROCESO, "Message error: %s",
					"Error en la recepcion de pedido de trace del sector");
			return -1;
		} //fin del if
		log_info(log, NOMBREPROCESO, "Message info: %s",
											"Exito en la recepcion de pedido de trace del sector");
		v= *(stTrace*)sPayload1;
		pArmadoResultadoTrace(v, log);

	} //fin del for


	return 0;
} //fin del fAtenderTrace

/******************************************************************************/
/* Nombre de Funcion: fAtenderEscribirSector                                  */
/* Parametros: iSocket: socket de comunicacion con el PPD.                    */
/*             st:Struct de escritura de sector                               */
/*             log:archivo de log                                             */
/* Descripcion: Funcion atiende el la escritura de un sector                  */
/******************************************************************************/
int fAtenderEscribirSector(int iSocket, stPEscrituraSector st,
		stREscrituraSector *stResultado, t_log *log) {
	/*Declaracion de variables locales*/
	stNIPC stES, str;
	void *sPayload;
	void *sPayload1 = NULL;
	stREscrituraSector*stRE=NULL;
	stResultado= (stREscrituraSector*)malloc(sizeof(stREscrituraSector));
	char sCadenaLog[1024] = "\0";
	int iResp;
	/*fin de la declaracion de variables locales*/

	stES.iPayloadDescriptor = ESCRITURA;
	stES.iType = 2;
	stES.sPayload_lenth = sizeof(stPEscrituraSector);
	strcpy(stES.sDescriptorOriginal, "NULL");
	sPayload = NULL;
	sPayload = (void *) &st;
	memset(sCadenaLog, '\0', 1024);

	if (fSendIPCCXsocket(iSocket, stES, sPayload, log) == 0) {
        sprintf(sCadenaLog, "%s%d", "Error en el envio de pedido de escritura  del sector ", st.iSector);
		log_error(log, NOMBREPROCESO, "Message error: %s",
				sCadenaLog);
		return -1;
	} //fin del if
	sprintf(sCadenaLog, "%s%d", "Exito en el envio de pedido de escritura  del sector ", st.iSector);
	log_info(log, NOMBREPROCESO, "Message info: %s",sCadenaLog);

	memset(sCadenaLog, '\0', 1024);


	if (fRecvIPCCXsocket(iSocket, &str, &sPayload1, log) <= 0) {
		sprintf(sCadenaLog,"%s%d", "Error en la recepcion de pedido de escritura del sector",st.iSector);
		log_error(log, NOMBREPROCESO, "Message error: %s",sCadenaLog);
		iResp = 1;
        return -1;
	} //fin del if
	sprintf(sCadenaLog,"%s%d", "Exito en la recepcion de pedido de escritura del sector",st.iSector);
	log_info(log, NOMBREPROCESO, "Message info: %s",sCadenaLog);


	*stResultado = *((stREscrituraSector*)sPayload1);

	return 0;
}

/******************************************************************************/
/* Nombre de Funcion: fAtenderLeerSector                                      */
/* Parametros: iSocket: socket de comunicacion con el PPD.                    */
/*             sector:sector a leer                                           */
/*             log:archivo de log                                             */
/* Descripcion: Funcion atiende la lectura de un sector                       */
/******************************************************************************/
int fAtenderLeerSector(int iSocket, int iSector, stRLecturaSector *stSLS,
		t_log *log) {
	/*declaracion de variables locales*/
	stNIPC stLS, str;
	void *sPayload = NULL;
	void *sPayload1 = NULL;
	int iResp;
	stRLecturaSector st;
	char sCadenaLog[1024] = "\0";
	/*fin de la declaracion de variables locales*/

	stLS.iPayloadDescriptor = LECTURA;
	stLS.iType = 3;
	stLS.sPayload_lenth = sizeof(int);
	strcpy(stLS.sDescriptorOriginal, "NULL");
	sPayload = (void *) &iSector;

	memset(sCadenaLog, '\0',1024);
	if (fSendIPCCXsocket(iSocket, stLS, sPayload, log) == 0) {

		sprintf(sCadenaLog,"%s%d", "Error en el envio de pedido de lectura  del sector ", iSector);
		log_error(log, NOMBREPROCESO, "Message error: %s",
				sCadenaLog);
		return -1;
	} //fin del if
	sprintf(sCadenaLog,"%s%d", "Exito en el envio de pedido de lectura del sector ",iSector);
	log_info(log, NOMBREPROCESO, "Message info: %s",
			sCadenaLog);
	memset(sCadenaLog, '\0',1024);
	if (fRecvIPCCXsocket(iSocket, &str, &sPayload1, log) <= 0) {
		sprintf(sCadenaLog,"%s%d", "Error en la recepcion de pedido de lectura del sector ",iSector);
		log_error(log, NOMBREPROCESO, "Message error: %s",
				sCadenaLog);
		iResp = 1;
		return -1;

	} //fin del if
	sprintf(sCadenaLog,"%s%d", "Exito en la recepcion de pedido de lectura del sector ",iSector);
	log_info(log, NOMBREPROCESO, "Message info: %s",
			sCadenaLog);
	st = *(stRLecturaSector *) sPayload1;
	*stSLS = st;
	return 0;
}
